Skip to content

== 和 === 区别

== 等号比较

两边先进行隐式类型转化再比较

shell
1. 基础类型相互比较:
   字符串、数字、布尔三者相互比较,都转化为数值再比较
   特殊:null == undefined 结果为 true,这是一个特列,除此以外 null == undefined 只与自身相等
   特殊:NaN 与任何都不想等,包括自身
   特殊:Symbol类型参与><+-运算比较会抛异常:TypeError, 但是可以使用 == === 比较,没啥意义因为其只与自身相等
2. 引用类型相互比较:
   两个引用类型比较,比较的是引用地址是否相同
3. 简单类型和引用类型比较
   先把引用类型化为原始再比较,原始值转化过程:obj.valueOf().toString()
   注意:对象的原始值是'[object Object]',而数组的原始值则不同,需要去掉[]再转化为字符串,比如: [] --> [] --> '' --> 0
   也就是:0 == [],结果为 true

=== 全等号比较

两边不进行类型转化直接比较类型和值,以下特殊情况,不等于自身的

shell
NaN 不等于 NaN,可通过 Number.isNaN(NaN) 判断值是否是 NaN
{} 不等于 {},比较引用地址
[] 不等于 [],比较引用地址
Symbol(1) 不等于 Symbol(1),比较引用地址
+0 恒等于 -0,可通过 Object.is(+0, -0),判断更严格 +0 不等于 -0

使用场景

shell
1. 由于 == 号两边会进行隐式类型转化再比较,所以建议所有场景都尽量使用 === 判断
2. 由于 undefined == null true,所以可以用 == 简化判断对象或者对象属性是否存在,即:
   obj == null 等价于 obj === null || obj === undefined
3. 如果判断引用类型的值是否相等
   可以使用 lodash _.isEqual() 方法判断引用类型的值是否相等

注意

所有使用 === 的场景都可以使用 Object.is(),Object.is() 还可以判断 NaN 与 +0 -0


说说 == 等于 和 === 全等 区别?

区别

shell
# 主要区别
等号两边先进行隐式类型转化再比较
全等号不进行转化,必须值与类型全部相同

## 等号两边隐式转化规则
1. 基础类型相互比较:字符串、数字、布尔三者相互比较,都转化为数值再比较
   特殊:null == undefined 结果为 true,这是一个特列,除此以外 null和undefined 只与自身相等
   特殊:NaN 与任何都不想等,包括自身,可通过 Number.isNaN(NaN) 判断值是否是 NaN
   特殊:Symbol类型参与><+-运算比较会抛异常:TypeError, 但是可以使用 == === 比较,没啥意义因为其只与自身相等
2. 引用类型相互比较:两个引用类型比较,比较的是引用是否指向同一个对象
3. 简单类型和引用类型比较:先把引用类型化为原始再比较,原始值转化过程:obj.valueOf().toString()
   注意:对象的原始值是'[object Object]',而数组的原始值则不同,需要去掉[]再转化为字符串,比如: [] --> '' --> 0
   也就是:0 == [],结果为 true

拓展

shell
# === 全等号判断的几种特殊情况
NaN 不等于 NaN,可通过 Number.isNaN(NaN) 判断值是否是 NaN
{} 不等于 {},比较引用地址
[] 不等于 [],比较引用地址
Symbol(1) 不等于 Symbol(1),比较引用地址
+0 恒等于 -0,可通过 Object.is(+0, -0),判断更严格 +0 不等于 -0
所有使用 ===  的场景都可以使用 Object.is(),Object.is() 还可以判断 NaN +0 -0

# 使用场景
1. 由于 == 号两边会进行隐式类型转化再比较,所以建议所有场景都尽量使用 === 判断
2. 由于 undefined == null true,所以可以用 == 简化判断对象或者对象属性是否存在,即:
   obj == null 等价于 obj === null || obj === undefined
3. 如果判断引用类型的值是否相等
   方案一:简单类型可以使用,JSON.stringify() 转字符判断
   方案三:复杂的可以递归比较
   除此之外可以使用 lodash _.isEqual() 方法判断引用类型的值是否相等